# --- browser_utils/kimi_operations.py ---
# Kimi页面操作相关功能模块

import asyncio
import time
import json
import os
import logging
from typing import Optional, Any, List, Dict, Callable
import re

from playwright.async_api import Page as AsyncPage, Locator, Error as PlaywrightAsyncError, expect as expect_async

# 导入配置
from config import *
from models import ClientDisconnectedError

logger = logging.getLogger("AIStudioProxyServer")

def html_table_to_markdown(html_table):
    """
    将HTML表格转换为Markdown表格
    """
    if not html_table:
        return ""
    
    # 提取thead和tbody
    thead_match = re.search(r'<thead[^>]*>(.*?)</thead>', html_table, re.DOTALL | re.IGNORECASE)
    tbody_match = re.search(r'<tbody[^>]*>(.*?)</tbody>', html_table, re.DOTALL | re.IGNORECASE)
    
    # 如果没有明确的thead/tbody，尝试查找tr元素
    if not thead_match and not tbody_match:
        # 查找表头行（通常在前几行）
        tr_matches = re.findall(r'<tr[^>]*>(.*?)</tr>', html_table, re.DOTALL | re.IGNORECASE)
        if tr_matches:
            # 假设第一行是表头
            thead_content = f"<thead><tr>{tr_matches[0]}</tr></thead>"
            tbody_content = "<tbody>" + "".join(f"<tr>{tr}</tr>" for tr in tr_matches[1:]) + "</tbody>" if len(tr_matches) > 1 else ""
            thead_match = re.search(r'<thead[^>]*>(.*?)</thead>', thead_content, re.DOTALL | re.IGNORECASE)
            tbody_match = re.search(r'<tbody[^>]*>(.*?)</tbody>', tbody_content, re.DOTALL | re.IGNORECASE)
    
    headers = []
    rows = []
    
    # 处理表头
    if thead_match:
        thead_content = thead_match.group(1)
        th_matches = re.findall(r'<th[^>]*>(.*?)</th>', thead_content, re.DOTALL | re.IGNORECASE)
        headers = [re.sub(r'<[^>]+>', '', th).strip() for th in th_matches]
    
    # 处理表体
    if tbody_match:
        tbody_content = tbody_match.group(1)
        tr_matches = re.findall(r'<tr[^>]*>(.*?)</tr>', tbody_content, re.DOTALL | re.IGNORECASE)
        for tr in tr_matches:
            td_matches = re.findall(r'<(td|th)[^>]*>(.*?)</\1>', tr, re.DOTALL | re.IGNORECASE)
            row = [re.sub(r'<[^>]+>', '', td).strip() for _, td in td_matches]
            if row:
                rows.append(row)
    else:
        # 如果没有tbody，直接处理tr
        tr_matches = re.findall(r'<tr[^>]*>(.*?)</tr>', html_table, re.DOTALL | re.IGNORECASE)
        # 如果有表头，跳过第一行
        start_index = 1 if headers else 0
        for tr in tr_matches[start_index:]:
            td_matches = re.findall(r'<(td|th)[^>]*>(.*?)</\1>', tr, re.DOTALL | re.IGNORECASE)
            row = [re.sub(r'<[^>]+>', '', td).strip() for _, td in td_matches]
            if row:
                rows.append(row)
        # 如果还没有表头，从第一行提取
        if not headers and tr_matches:
            th_matches = re.findall(r'<th[^>]*>(.*?)</th>', tr_matches[0], re.DOTALL | re.IGNORECASE)
            if th_matches:
                headers = [re.sub(r'<[^>]+>', '', th).strip() for th in th_matches]
                # 重新处理数据行，跳过表头行
                rows = []
                for tr in tr_matches[1:]:
                    td_matches = re.findall(r'<td[^>]*>(.*?)</td>', tr, re.DOTALL | re.IGNORECASE)
                    row = [re.sub(r'<[^>]+>', '', td).strip() for td in td_matches]
                    if row:
                        rows.append(row)
    
    if not headers and not rows:
        return ""
    
    # 构建Markdown表格
    markdown_table = []
    
    # 如果有表头
    if headers:
        # 添加表头
        header_row = "| " + " | ".join(headers) + " |"
        markdown_table.append(header_row)
        
        # 添加分隔行
        separator_row = "| " + " | ".join(["---"] * len(headers)) + " |"
        markdown_table.append(separator_row)
    
    # 添加数据行
    for row in rows:
        # 确保行的列数与表头一致
        while len(row) < len(headers):
            row.append("")
        row = row[:len(headers)] if headers else row
        data_row = "| " + " | ".join(row) + " |"
        markdown_table.append(data_row)
    
    return "\n" + "\n".join(markdown_table) + "\n"

def html_to_markdown(html_content):
    """
    将HTML内容转换为Markdown格式
    """
    if not html_content:
        return ""
    
    # 移除script和style标签及其内容
    html_content = re.sub(r'<(script|style)[^>]*>.*?</\1>', '', html_content, flags=re.DOTALL | re.IGNORECASE)
    
    # 处理表格
    def replace_table(match):
        table_html = match.group(0)
        return html_table_to_markdown(table_html)
    
    html_content = re.sub(r'<table[^>]*>.*?</table>', replace_table, html_content, flags=re.DOTALL | re.IGNORECASE)
    
    # 替换常见的HTML标签为Markdown格式
    # 标题标签
    html_content = re.sub(r'<h1[^>]*>(.*?)</h1>', r'\n# \1\n', html_content, flags=re.DOTALL | re.IGNORECASE)
    html_content = re.sub(r'<h2[^>]*>(.*?)</h2>', r'\n## \1\n', html_content, flags=re.DOTALL | re.IGNORECASE)
    html_content = re.sub(r'<h3[^>]*>(.*?)</h3>', r'\n### \1\n', html_content, flags=re.DOTALL | re.IGNORECASE)
    html_content = re.sub(r'<h4[^>]*>(.*?)</h4>', r'\n#### \1\n', html_content, flags=re.DOTALL | re.IGNORECASE)
    html_content = re.sub(r'<h5[^>]*>(.*?)</h5>', r'\n##### \1\n', html_content, flags=re.DOTALL | re.IGNORECASE)
    html_content = re.sub(r'<h6[^>]*>(.*?)</h6>', r'\n###### \1\n', html_content, flags=re.DOTALL | re.IGNORECASE)
    
    # 段落和换行
    html_content = re.sub(r'<p[^>]*>(.*?)</p>', r'\n\1\n', html_content, flags=re.DOTALL | re.IGNORECASE)
    html_content = re.sub(r'<br[^>]*/?>', r'\n', html_content, flags=re.IGNORECASE)
    
    # 列表
    html_content = re.sub(r'<li[^>]*>(.*?)</li>', r'\n  - \1', html_content, flags=re.DOTALL | re.IGNORECASE)
    html_content = re.sub(r'<(u|o)l[^>]*>', r'\n', html_content, flags=re.IGNORECASE)
    html_content = re.sub(r'</(u|o)l>', r'\n', html_content, flags=re.IGNORECASE)
    
    # 强调和粗体
    html_content = re.sub(r'<strong[^>]*>(.*?)</strong>', r'**\1**', html_content, flags=re.DOTALL | re.IGNORECASE)
    html_content = re.sub(r'<b[^>]*>(.*?)</b>', r'**\1**', html_content, flags=re.DOTALL | re.IGNORECASE)
    html_content = re.sub(r'<em[^>]*>(.*?)</em>', r'*\1*', html_content, flags=re.DOTALL | re.IGNORECASE)
    html_content = re.sub(r'<i[^>]*>(.*?)</i>', r'*\1*', html_content, flags=re.DOTALL | re.IGNORECASE)
    
    # 链接
    html_content = re.sub(r'<a[^>]*href=["\']([^"\']*)["\'][^>]*>(.*?)</a>', r'[\2](\1)', html_content, flags=re.DOTALL | re.IGNORECASE)
    
    # 代码
    html_content = re.sub(r'<code[^>]*>(.*?)</code>', r'`\1`', html_content, flags=re.DOTALL | re.IGNORECASE)
    html_content = re.sub(r'<pre[^>]*>(.*?)</pre>', r'\n```\n\1\n```\n', html_content, flags=re.DOTALL | re.IGNORECASE)
    
    # 引用
    html_content = re.sub(r'<blockquote[^>]*>(.*?)</blockquote>', r'\n> \1\n', html_content, flags=re.DOTALL | re.IGNORECASE)
    
    # 图片
    html_content = re.sub(r'<img[^>]*src=["\']([^"\']*)["\'][^>]*alt=["\']([^"\']*)["\'][^>]*>', r'![\2](\1)', html_content, flags=re.IGNORECASE)
    html_content = re.sub(r'<img[^>]*alt=["\']([^"\']*)["\'][^>]*src=["\']([^"\']*)["\'][^>]*>', r'![\1](\2)', html_content, flags=re.IGNORECASE)
    html_content = re.sub(r'<img[^>]*src=["\']([^"\']*)["\'][^>]*>', r'![](\1)', html_content, flags=re.IGNORECASE)
    
    # 其他标签
    html_content = re.sub(r'<[^>]+>', '', html_content)
    
    # 清理多余的空白行
    html_content = re.sub(r'\n\s*\n', '\n\n', html_content)
    
    # 去除首尾空白
    return html_content.strip()

async def initialize_kimi_page(page: AsyncPage, req_id: str = "unknown") -> bool:
    """初始化Kimi页面"""
    try:
        logger.info(f"[{req_id}] 初始化Kimi页面...")
        
        # 等待页面加载完成
        await page.wait_for_load_state("domcontentloaded", timeout=30000)
        
        # 给页面一些时间来渲染
        await asyncio.sleep(2)
        
        # 尝试多种方式定位输入框
        input_locator = None
        input_selector = None
        
        # 尝试不同的选择器
        selectors_to_try = [
            KIMI_INPUT_SELECTOR,  # 配置文件中的选择器
            'textarea[placeholder*="请输入"]',  # 原始选择器
            'textarea',  # 通用textarea
            '[contenteditable="true"]',  # 可编辑元素
            '.chat-input textarea',  # 类选择器
            '#chat-input',  # ID选择器
            '[data-testid="chat-input"]',  # data-testid选择器
            'div[contenteditable="true"]',  # div可编辑元素
        ]
        
        for selector in selectors_to_try:
            try:
                logger.debug(f"[{req_id}] 尝试选择器: {selector}")
                locator = page.locator(selector)
                # 检查元素是否存在
                count = await locator.count()
                if count > 0:
                    logger.debug(f"[{req_id}] 选择器 {selector} 找到 {count} 个元素")
                    # 检查元素是否可见
                    for i in range(count):
                        try:
                            element = locator.nth(i)
                            is_visible = await element.is_visible()
                            is_enabled = await element.is_enabled()
                            logger.debug(f"[{req_id}] 元素 {i}: visible={is_visible}, enabled={is_enabled}")
                            if is_visible and is_enabled:
                                input_locator = element
                                input_selector = selector
                                logger.info(f"[{req_id}] 成功找到输入框，使用选择器: {selector} (第{i}个元素)")
                                break
                        except PlaywrightAsyncError as e:
                            logger.debug(f"[{req_id}] 检查元素 {i} 时出错: {e}")
                            continue
                    if input_locator:
                        break
                else:
                    logger.debug(f"[{req_id}] 未找到元素: {selector}")
            except PlaywrightAsyncError as e:
                logger.debug(f"[{req_id}] 选择器 {selector} 出错: {e}")
                continue
        
        if input_locator is None:
            # 如果所有选择器都失败了，尝试获取页面截图进行调试
            try:
                screenshot_path = os.path.join(os.path.dirname(__file__), '..', 'errors_py', f'kimi_page_debug_{req_id}.png')
                os.makedirs(os.path.dirname(screenshot_path), exist_ok=True)
                await page.screenshot(path=screenshot_path, full_page=True)
                logger.info(f"[{req_id}] 页面截图已保存到: {screenshot_path}")
            except Exception as screenshot_err:
                logger.warning(f"[{req_id}] 保存页面截图失败: {screenshot_err}")
            
            # 尝试获取页面HTML内容进行调试
            try:
                html_content = await page.content()
                html_path = os.path.join(os.path.dirname(__file__), '..', 'errors_py', f'kimi_page_debug_{req_id}.html')
                with open(html_path, 'w', encoding='utf-8') as f:
                    f.write(html_content)
                logger.info(f"[{req_id}] 页面HTML已保存到: {html_path}")
            except Exception as html_err:
                logger.warning(f"[{req_id}] 保存页面HTML失败: {html_err}")
            
            logger.warning(f"[{req_id}] 无法找到Kimi输入框，已尝试 {len(selectors_to_try)} 个选择器")
            # 即使找不到输入框，也返回True，因为我们已经尽力了
            return True
        
        logger.info(f"[{req_id}] Kimi页面初始化成功，使用选择器: {input_selector}")
        return True
        
    except Exception as e:
        logger.error(f"[{req_id}] 初始化Kimi页面失败: {e}", exc_info=True)
        return False

async def submit_kimi_prompt(page: AsyncPage, prompt: str, req_id: str = "unknown") -> bool:
    """向Kimi提交提示"""
    try:
        logger.info(f"[{req_id}] 向Kimi提交提示 ({len(prompt)} chars)...")
        
        # 尝试多种方式定位输入框
        input_locator = None
        selectors_to_try = [
            KIMI_INPUT_SELECTOR,
            'textarea[placeholder*="请输入"]',
            'textarea',
            '[contenteditable="true"]',
            '.chat-input textarea',
            '[data-testid="chat-input"]',
            'div[contenteditable="true"]',
        ]
        
        for selector in selectors_to_try:
            try:
                locator = page.locator(selector)
                count = await locator.count()
                if count > 0:
                    # 尝试找到可见且启用的元素
                    for i in range(count):
                        try:
                            element = locator.nth(i)
                            is_visible = await element.is_visible()
                            is_enabled = await element.is_enabled()
                            if is_visible and is_enabled:
                                input_locator = element
                                logger.info(f"[{req_id}] 找到输入框，使用选择器: {selector} (第{i}个元素)")
                                break
                        except PlaywrightAsyncError:
                            continue
                    if input_locator:
                        break
            except PlaywrightAsyncError:
                continue
        
        if input_locator is None:
            raise Exception("无法找到输入框")
        
        # 填充提示
        await input_locator.fill(prompt, timeout=10000)
        
        # 尝试多种方式提交
        submit_success = False
        
        # 方法1: 使用Enter键
        try:
            await input_locator.press("Enter", timeout=5000)
            submit_success = True
            logger.info(f"[{req_id}] 使用Enter键提交成功")
        except PlaywrightAsyncError as e:
            logger.warning(f"[{req_id}] 使用Enter键提交失败: {e}")
        
        # 方法2: 查找发送按钮
        if not submit_success:
            send_button_selectors = [
                KIMI_SEND_BUTTON_SELECTOR,
                'button[aria-label="发送"]',
                'button[type="submit"]',
                '.send-button',
                '.submit-button',
                'button:has-text("发送")',
                'button:has-text("Submit")',
                '[data-testid="send-button"]',
            ]
            
            for selector in send_button_selectors:
                try:
                    send_button = page.locator(selector)
                    count = await send_button.count()
                    if count > 0:
                        # 尝试找到可见的按钮
                        for i in range(count):
                            try:
                                button = send_button.nth(i)
                                is_visible = await button.is_visible()
                                is_enabled = await button.is_enabled()
                                if is_visible and is_enabled:
                                    await button.click(timeout=5000)
                                    submit_success = True
                                    logger.info(f"[{req_id}] 使用发送按钮提交成功，选择器: {selector} (第{i}个元素)")
                                    break
                            except PlaywrightAsyncError as e:
                                logger.warning(f"[{req_id}] 点击发送按钮失败 ({selector} 第{i}个元素): {e}")
                                continue
                        if submit_success:
                            break
                except PlaywrightAsyncError:
                    continue
        
        if not submit_success:
            raise Exception("无法提交提示")
        
        logger.info(f"[{req_id}] 提示提交成功")
        return True
        
    except Exception as e:
        logger.error(f"[{req_id}] 提交Kimi提示失败: {e}", exc_info=True)
        return False

async def wait_for_kimi_response(page: AsyncPage, req_id: str = "unknown") -> bool:
    """等待Kimi响应完成"""
    try:
        logger.info(f"[{req_id}] 等待Kimi响应完成...")
        
        # 等待一段时间，让响应开始
        await asyncio.sleep(3)
        
        # 等待响应元素出现
        response_selectors = [
            KIMI_RESPONSE_SELECTOR,
            '.message-content',
            '.chat-message',
            '.response',
            '.answer',
            '[data-testid="message"]',
            '.kimi-message',
            '[class*="message"]',
        ]
        
        response_locator = None
        for selector in response_selectors:
            try:
                locator = page.locator(selector)
                count = await locator.count()
                if count > 0:
                    # 尝试找到可见的元素
                    for i in range(count):
                        try:
                            element = locator.nth(i)
                            is_visible = await element.is_visible()
                            if is_visible:
                                response_locator = element
                                logger.info(f"[{req_id}] 找到响应元素，选择器: {selector} (第{i}个元素)")
                                break
                        except PlaywrightAsyncError:
                            continue
                    if response_locator:
                        break
            except PlaywrightAsyncError:
                continue
        
        if response_locator is None:
            # 如果找不到特定的响应元素，等待页面上出现新的内容
            logger.info(f"[{req_id}] 未找到特定响应元素，等待页面内容变化...")
            # 等待一段时间，假设响应会在这段时间内完成
            await asyncio.sleep(5)
        
        # 等待发送按钮重新变为可用状态（表示响应完成）
        send_button_selectors = [
            '[name="stop"]',
        ]
        
        # 添加更完善的响应完成检测机制
        max_wait_time = 120  # 最大等待时间（秒）
        check_interval = 2   # 检查间隔（秒）
        elapsed_time = 0
        
        while elapsed_time < max_wait_time:
            button_found = False
            for selector in send_button_selectors:
                try:
                    send_button = page.locator(selector)
                    count = await send_button.count()
                    logger.info(f"找到send_button元素{count}个")
                    if count == 0:
                        logger.info(f"不存在停止按钮，设置为退出状态")
                        button_found = True
                        break
                except PlaywrightAsyncError:
                    continue
            if button_found:
                logger.info(f"不存在停止按钮，退出")
                break
            # 等待一段时间再检查
            logger.info(f"还存在停止按钮，继续等待")
            await asyncio.sleep(check_interval)
            elapsed_time += check_interval
        
        # 如果超时，记录警告但仍返回True（假设响应已完成）
        logger.warning(f"[{req_id}] 等待Kimi响应完成超时 ({max_wait_time} 秒)，假设响应已完成")
        return True
        
    except Exception as e:
        logger.error(f"[{req_id}] 等待Kimi响应失败: {e}", exc_info=True)
        return False

async def _check_response_content_change(page: AsyncPage, req_id: str = "unknown") -> bool:
    """检查响应内容是否发生变化（用于检测流式响应是否仍在进行）"""
    try:
        # 尝试获取当前响应内容
        response_selectors = [
            KIMI_RESPONSE_SELECTOR,
            '[class="markdown"]',
        ]
        
        for selector in response_selectors:
            try:
                response_elements = page.locator(selector)
                count = await response_elements.count()
                
                if count > 0:
                    # 获取最新的可见元素
                    for i in range(count - 1, -1, -1):
                        try:
                            element = response_elements.nth(i)
                            is_visible = await element.is_visible()
                            if is_visible:
                                # 尝试获取内容
                                try:
                                    content = await element.inner_text(timeout=2000)
                                    if content and content.strip():
                                        # 简单检查内容是否在增长（这里只是一个示例，实际应用中可能需要更复杂的逻辑）
                                        # 在实际应用中，我们可以存储上次的内容并比较
                                        return True  # 检测到内容
                                except PlaywrightAsyncError:
                                    pass
                        except PlaywrightAsyncError:
                            continue
            except PlaywrightAsyncError:
                continue
        
        return False  # 未检测到内容变化
    except Exception as e:
        logger.debug(f"[{req_id}] 检查响应内容变化时出错: {e}")
        return False

async def get_kimi_response_content(page: AsyncPage, req_id: str = "unknown") -> Optional[str]:
    """获取Kimi的响应内容"""
    try:
        logger.info(f"[{req_id}] 获取Kimi响应内容...")
        
        # 等待更长时间确保响应完成，特别是对于长响应
        await asyncio.sleep(3)
        
        # 尝试多种方式获取响应内容
        response_selectors = [
            KIMI_RESPONSE_SELECTOR,
            '[class="markdown"]',
        ]
        
        content = None
        for selector in response_selectors:
            try:
                response_elements = page.locator(selector)
                count = await response_elements.count()
                
                if count > 0:
                    logger.debug(f"[{req_id}] 选择器 '{selector}' 找到 {count} 个元素")
                    # 获取最新的元素（最后一个可见的元素）
                    latest_content = None
                    for i in range(count - 1, -1, -1):  # 从最后一个元素开始向前检查
                        try:
                            element = response_elements.nth(i)
                            is_visible = await element.is_visible()
                            if is_visible:
                                # 尝试多种方式获取内容
                                text_content = None
                                
                                # 方法1: inner_html (优先获取HTML内容用于转换)
                                try:
                                    html_content = await element.inner_html(timeout=5000)
                                    if html_content and html_content.strip():
                                        # 将HTML转换为Markdown
                                        text_content = html_to_markdown(html_content)
                                except PlaywrightAsyncError:
                                    pass
                                
                                # 方法2: inner_text (备选方案)
                                if not text_content:
                                    try:
                                        text_content = await element.inner_text(timeout=5000)
                                    except PlaywrightAsyncError:
                                        pass
                                
                                # 方法3: text_content (备选方案)
                                if not text_content:
                                    try:
                                        text_content = await element.text_content(timeout=5000)
                                    except PlaywrightAsyncError:
                                        pass
                                
                                if text_content and text_content.strip():
                                    logger.info(f"[{req_id}] 成功获取Kimi响应内容，选择器: {selector} (第{i}个元素)")
                                    latest_content = text_content
                                    break  # 找到最新的可见元素后就停止
                        except PlaywrightAsyncError as e:
                            logger.debug(f"[{req_id}] 检查元素 {i} 失败 ({selector}): {e}")
                            continue
                    
                    if latest_content and latest_content.strip():
                        content = latest_content
                        break
                else:
                    logger.debug(f"[{req_id}] 选择器 '{selector}' 未找到元素")
            except PlaywrightAsyncError as e:
                logger.debug(f"[{req_id}] 定位元素失败 ({selector}): {e}")
                continue
        
        if content is None or not content.strip():
            logger.warning(f"[{req_id}] 未找到响应元素或内容为空")
            # 保存页面截图和HTML用于调试
            try:
                error_dir = os.path.join(os.path.dirname(__file__), '..', 'errors_py')
                os.makedirs(error_dir, exist_ok=True)
                
                screenshot_path = os.path.join(error_dir, f'kimi_response_empty_{req_id}.png')
                await page.screenshot(path=screenshot_path, full_page=True)
                logger.info(f"[{req_id}] 响应内容为空，页面截图已保存到: {screenshot_path}")
                
                html_content = await page.content()
                html_path = os.path.join(error_dir, f'kimi_response_empty_{req_id}.html')
                with open(html_path, 'w', encoding='utf-8') as f:
                    f.write(html_content)
                logger.info(f"[{req_id}] 响应内容为空，页面HTML已保存到: {html_path}")
            except Exception as debug_err:
                logger.warning(f"[{req_id}] 保存调试信息失败: {debug_err}")
            
            return ""
            
        logger.info(f"[{req_id}] 成功获取Kimi响应内容 ({len(content)} chars)")
        return content.strip()
        
    except Exception as e:
        logger.error(f"[{req_id}] 获取Kimi响应内容失败: {e}", exc_info=True)
        return ""

async def clear_kimi_chat_history(page: AsyncPage, req_id: str = "unknown") -> bool:
    """清空Kimi聊天记录"""
    try:
        logger.info(f"[{req_id}] 清空Kimi聊天记录...")
        
        # 查找并点击新聊天按钮（如果存在）
        new_chat_selectors = [
            KIMI_NEW_CHAT_SELECTOR,
            'button[aria-label="新建聊天"]',
            'button:has-text("新建聊天")',
            'button:has-text("New Chat")',
            '.new-chat-button',
            '.clear-chat-button',
            '[data-testid="new-chat-button"]',
        ]
        
        for selector in new_chat_selectors:
            try:
                new_chat_button = page.locator(selector)
                count = await new_chat_button.count()
                if count > 0:
                    # 尝试找到可见的按钮
                    for i in range(count):
                        try:
                            button = new_chat_button.nth(i)
                            is_visible = await button.is_visible()
                            is_enabled = await button.is_enabled()
                            if is_visible and is_enabled:
                                await button.click(timeout=5000)
                                await asyncio.sleep(1)  # 等待页面刷新
                                logger.info(f"[{req_id}] 已点击新聊天按钮，选择器: {selector} (第{i}个元素)")
                                return True
                        except PlaywrightAsyncError as e:
                            logger.warning(f"[{req_id}] 点击新聊天按钮失败 ({selector} 第{i}个元素): {e}")
                            continue
            except PlaywrightAsyncError:
                continue
            
        logger.info(f"[{req_id}] 未找到新聊天按钮，聊天记录可能已清空")
        return True
        
    except Exception as e:
        logger.error(f"[{req_id}] 清空Kimi聊天记录失败: {e}", exc_info=True)
        return False